package com.hh.gateway.filter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.Map;

/**
 * 定义一个过滤器
 * 十个过滤器
 */
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {

    /**
     * 全局断言
     * 这个就是过滤的方法
     * 过滤器链模式
     * 责任链模式
     * 网关里面有使用 mybatis 二级缓存有变种责任链
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 针对请求的过滤 拿到请求 header url 参数...
        ServerHttpRequest request = exchange.getRequest();
        // HttpServletRequest 这个是web里面的
        // ServerHttpRequest 这个是webFlux里卖弄的 响应式里面的
        String path = request.getURI().getPath();
        System.out.println("path = " + path);
        HttpHeaders headers = request.getHeaders();
        System.out.println("headers = " + headers);
        String name = request.getMethod().name();
        System.out.println("name = " + name);
        String hostName = request.getRemoteAddress().getHostName();
        // ipv6 地址
        System.out.println("hostName = " + hostName);
        // ipv4 地址
        String ip = request.getHeaders().getHost().getHostString();
        System.out.println("ip = " + ip);
        ServerHttpResponse response = exchange.getResponse();
        // 用了微服务 肯定是前后端分离的 前后端分离 前后通过 json 交互
        // {"code": 200, msg: "ok"}
        // 去设置编码 响应头内设置
//        response.getHeaders().set("Content-Type", "application/json;charset=UTF-8");
//        // 组装业务返回值
//        Map<String, Object> map = new HashMap<>(4);
//        map.put("code", HttpStatus.UNAUTHORIZED.value());
//        map.put("msg", "你未授权");
//        ObjectMapper objectMapper = new ObjectMapper();
//        try {
//            // 把map转成一个字节
//            byte[] bytes = objectMapper.writeValueAsBytes(map);
//            // 获取字节工厂 通过buffer工厂将字节包装成以恶个数据包
//            DataBuffer wrap = response.bufferFactory().wrap(bytes);
//            return response.writeWith(Mono.just(wrap));
//        } catch (JsonProcessingException e) {
//            e.printStackTrace();
//        }
//        // 放行 到下一个过滤器中
        return chain.filter(exchange);
    }

    /**
     * 排序 指定顺序的方法
     * 越小越先执行
     * 最大值
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}
